(defun cube(x)
  (expt x 3))

(defun first-cube(digs)
  (loop for i = 2 then (1+ i)
       when  (= digs (digits-no (cube i)))
       do (return i)))

(defun generate-cubes-of-digits(digs)
  (loop for i = (first-cube digs) then (1+ i)
     for cube = (digits (cube i))
     until (> (length cube) digs)
     collect (list i (sort cube #'<))))

(defun count-in-list(elem l)
;  (print  (caaddr l))
  (if (null l) 
      0
      (+ (if (equal (cadr (cadr l)) elem) 1 0) (count-in-list elem (cdr l)))))

(defun count-duplicates (l)
  (loop for i in l collect (cons (car i) (count-in-list (cadr i) l))))

(defun max-duplicates-with-sort(digs)
  (first (sort (count-duplicates (generate-cubes-of-digits digs)) 
	#'(lambda (x y) (if (= (car x) (car y)) 
			    (< (car x) (car y))
			    (> (cdr x) (cdr y)))))))

(defun max-duplicates(dits)
  (loop for i in (count-duplicates (generate-cubes-of-digits digs))
       with min = 
       when 
       maximize (cdr i)))




;------------------
(defun digits (num)
  (map 'list
       #'(lambda (char) (read-from-string (string char)))
       (prin1-to-string num)))

(defun sorted-digits (num)
  (sort (digits num) #'<))

(defun smallest-expt-permute (ways)
  (setq digit-hash (make-hash-table :test 'equal))
  (loop for i from 1
     do (let* ((digits (sorted-digits (expt i 3)))
	       (newentry (push i (gethash digits digit-hash))))
	  (if (>= (length newentry) ways)
	      (return (expt (car (last newentry)) 3))))))

(defun euler62 ()
  (smallest-expt-permute 5)) 